package com.higgins.client.agentapp.components;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.higgins.client.GreetingService;
import com.higgins.client.GreetingServiceAsync;
import com.higgins.client.agentapp.datamodel.AdvertisedJobDTO;
import com.higgins.client.agentapp.datamodel.AgencyDTO;
import com.higgins.client.agentapp.datamodel.AgentDTO;
import com.higgins.client.agentapp.datamodel.JobSiteDTO;
import com.higgins.client.agentapp.service.AgentAppService;
import com.higgins.client.agentapp.service.AgentAppServiceAsync;
import com.higgins.client.dataModel.CoveringLetterDTO;
import com.higgins.client.dataModel.RecipientCountDTO;
import com.higgins.client.dataModel.StatusDTO;
import com.higgins.client.dataModel.StrategyDTO;
import com.higgins.client.dataModel.StrategyRecipientCountDTO;
import com.higgins.client.dataModel.StrategyRecipientDTO;
import com.higgins.client.generic.components.GenericColumn;
import com.higgins.client.generic.components.GenericTable;

public class AdvertisedJobTable extends GenericTable	{
	private static final Logger log = Logger.getLogger(AdvertisedJobTable.class.getName());
	private final AgentAppServiceAsync agentAppService = GWT
			.create(AgentAppService.class);
	
	public AdvertisedJobTable(AdvertisedJobColumns columns)	{
		super(columns);
	}
	public void listsLoaded()	{
		retrieveDTOs();
	}
	
	protected void addObject(int row, int column, Object object)	{
		ensureRowAvailable(row);
		GenericColumn genericColumn = genericColumns.getColumn(column);
		if (genericColumn.getType().equals(JobSiteDTO.class))	{
			addJobSiteDTO(row, column, object, genericColumn);
		}	else if (genericColumn.getType().equals(AgencyDTO.class))	{
			addAgencyDTO(row, column, object, genericColumn);
		} 	else if (genericColumn.getType().equals(AgentDTO.class))	{
			addAgentDTO(row, column, object, genericColumn);
		} 
	}
	protected void addJobSiteDTO(int row, int column, Object object, GenericColumn genericColumn)	{
		final ListBox listBox = new ListBox();
		final int finalRow = row; 
		int count = 1;
		listBox.addItem("");
		List<Object> list = genericColumn!=null?genericColumn.getList():new ArrayList<Object>();
		for (Object listItem:(list!=null?list:new ArrayList<Object>()))	{
			String item = ((JobSiteDTO)listItem).getName();
			listBox.addItem(item);
			if (((String)object).equals(item))	{
				listBox.setSelectedIndex(count);
			}
			count++;
		}
		listBox.addChangeHandler(new ChangeHandler() {
	        public void onChange(ChangeEvent changeEvent) {
	            SelectElement selectElement = listBox.getElement().cast();
	            selectElement.getOptions().getItem(0).setDisabled(true);
	            updateItemCell(finalRow);

	        }
	    });
		setWidget(row, column, listBox);
 		getCellFormatter().addStyleName(row, column, "FlexTable-normCell");		
	}	
	protected void addAgencyDTO(int row, int column, Object object, GenericColumn genericColumn)	{
		final ListBox listBox = new ListBox();
		final int finalRow = row; 
		int count = 1;
		listBox.addItem("");
		List<Object> list = genericColumn!=null?genericColumn.getList():new ArrayList<Object>();
		for (Object listItem:(list!=null?list:new ArrayList<Object>()))	{
			String item = ((AgencyDTO)listItem).getName();
			listBox.addItem(item);
			if (((String)object).equals(item))	{
				listBox.setSelectedIndex(count);
			}
			count++;
		}
		listBox.addChangeHandler(new ChangeHandler() {
	        public void onChange(ChangeEvent changeEvent) {
	            SelectElement selectElement = listBox.getElement().cast();
	            selectElement.getOptions().getItem(0).setDisabled(true);
	            updateItemCell(finalRow);

	        }
	    });
		setWidget(row, column, listBox);
 		getCellFormatter().addStyleName(row, column, "FlexTable-normCell");		
	}
	protected void addAgentDTO(int row, int column, Object object, GenericColumn genericColumn)	{
		final ListBox listBox = new ListBox();
		final int finalRow = row; 
		int count = 1;
		listBox.addItem("");
		List<Object> list = genericColumn!=null?genericColumn.getList():new ArrayList<Object>();
		for (Object listItem:(list!=null?list:new ArrayList<Object>()))	{
			String item = ((AgentDTO)listItem).getName();
			listBox.addItem(item);
			if (((String)object).equals(item))	{
				listBox.setSelectedIndex(count);
			}
			count++;
		}
		listBox.addChangeHandler(new ChangeHandler() {
	        public void onChange(ChangeEvent changeEvent) {
	            SelectElement selectElement = listBox.getElement().cast();
	            selectElement.getOptions().getItem(0).setDisabled(true);
	            updateItemCell(finalRow);

	        }
	    });
		setWidget(row, column, listBox);
 		getCellFormatter().addStyleName(row, column, "FlexTable-normCell");		
	}		
	
	private List<List<Object>> convertDTOtoRowArray(List<AdvertisedJobDTO> advertisedJobDTOs)	{
		List<List<Object>> rows = new ArrayList<List<Object>>();
		for (AdvertisedJobDTO advertisedJobDTO:advertisedJobDTOs)	{
			List<Object> row = new ArrayList<Object>();
			row.add(advertisedJobDTO.getId());
            row.add(advertisedJobDTO.getTimestamp()!=null?advertisedJobDTO.getTimestamp():"");
            row.add(advertisedJobDTO.getJobSiteDTO()!=null?advertisedJobDTO.getJobSiteDTO().getName():"");
			row.add(advertisedJobDTO.getAgencyDTO()!=null?advertisedJobDTO.getAgencyDTO().getName():"");
			row.add(advertisedJobDTO.getAgentDTO()!=null?advertisedJobDTO.getAgentDTO().getName():"");
			row.add(advertisedJobDTO.getDescription()!=null?advertisedJobDTO.getDescription():"");
			row.add(advertisedJobDTO.getJobCode()!=null?advertisedJobDTO.getJobCode():"");
			rows.add(row);
		}
		return rows;
	}
	
	public void updateItemCell(int row)	{
		AdvertisedJobDTO advertisedJobDTO = new AdvertisedJobDTO();
		advertisedJobDTO.setId(getId(row));
		advertisedJobDTO.setTimestamp(getDate(row, 1));
		advertisedJobDTO.setJobSiteDTO(getJobSiteDTO(row, 2));
		advertisedJobDTO.setAgencyDTO(getAgencyDTO(row, 3));
		advertisedJobDTO.setAgentDTO(getAgentDTO(row, 4));
		advertisedJobDTO.setDescription(getText(row, 5));
		advertisedJobDTO.setJobCode(getText(row, 6));
		updateRow(advertisedJobDTO);
	}
	
	protected void retrieveDTOs()	{
		try {
			agentAppService.retrieveAdvertisedJobs(new AsyncCallback<List<AdvertisedJobDTO>>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("FixedOutgoingDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(List<AdvertisedJobDTO> result) {
						loadData(convertDTOtoRowArray(result));
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("FixedOutgoingDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} */
	}	

	private void updateRow(AdvertisedJobDTO advertisedJobDTO)	{
		try {
			agentAppService.updateAdvertisedJob(advertisedJobDTO, new AsyncCallback<String>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("FixedOutgoingDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						setRowIdAfterUpdate(result);
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("FixedOutgoingDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} 		*/
	}
	
	public JobSiteDTO getJobSiteDTO(int row, int column)	{
		try	{
			ListBox listBox = (ListBox)getWidget(row, column);
			int selectedIndex = listBox.getSelectedIndex();
			String jobSite = listBox.getItemText(selectedIndex);
			return getJobSiteDTO(jobSite);
		} catch (Exception e)	{
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	public JobSiteDTO getJobSiteDTO(String string)	{
		for (GenericColumn genericColumn:genericColumns.getColumns())	{
			if (genericColumn.getType()==(JobSiteDTO.class))	{
				if (genericColumn.getList()!=null)	{
					for (JobSiteDTO dto:(List<JobSiteDTO>)genericColumn.getList())	{
						if (dto.getName().equals(string))	{
							return dto;
						}
					}
				}
			}
		}
		return null;
	}
	
	public AgencyDTO getAgencyDTO(int row, int column)	{
		try	{
			ListBox listBox = (ListBox)getWidget(row, column);
			int selectedIndex = listBox.getSelectedIndex();
			String jobSite = listBox.getItemText(selectedIndex);
			return getAgencyDTO(jobSite);
		} catch (Exception e)	{
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	public AgencyDTO getAgencyDTO(String string)	{
		for (GenericColumn genericColumn:genericColumns.getColumns())	{
			if (genericColumn.getType()==(AgencyDTO.class))	{
				if (genericColumn.getList()!=null)	{
					for (AgencyDTO dto:(List<AgencyDTO>)genericColumn.getList())	{
						if (dto.getName().equals(string))	{
							return dto;
						}
					}
				}
			}
		}
		return null;
	}	
	public AgentDTO getAgentDTO(int row, int column)	{
		try	{
			ListBox listBox = (ListBox)getWidget(row, column);
			int selectedIndex = listBox.getSelectedIndex();
			String agent = listBox.getItemText(selectedIndex);
			return getAgentDTO(agent);
		} catch (Exception e)	{
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	public AgentDTO getAgentDTO(String string)	{
		for (GenericColumn genericColumn:genericColumns.getColumns())	{
			if (genericColumn.getType()==(AgentDTO.class))	{
				if (genericColumn.getList()!=null)	{
					for (AgentDTO dto:(List<AgentDTO>)genericColumn.getList())	{
						if (dto.getName().equals(string))	{
							return dto;
						}
					}
				}
			}
		}
		return null;
	}		
	protected String statusField(StrategyDTO dto)	{
		Integer status = dto.getStatus();
		if (status!=null)	{
			switch (status)	{
			case 0:
				return "None";
			case 1:
				return "Requested";
			case 2:
				return "Generated";
			case 3:
				return "Posted";
			}
		} 
		return "";
	}
	protected Integer getStatusColumn()	{
		for(GenericColumn genericColumn:genericColumns.getColumns())	{
			if (genericColumn.getType().equals(StatusDTO.class))
				return genericColumn.getIndex();
		}
		return null;
	}
	
	protected void checkBoxSet(Long id) {
	    agentAppService.deleteAdvertisedJob(id, new AsyncCallback<Boolean>() {
            @Override
            public void onFailure(Throwable caught) {
                
            }

            @Override
            public void onSuccess(Boolean result) {
                refresh();
            } });
	}

}